package org.xxpay.pay.channel.nps;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.xxpay.common.util.Util;
import org.xxpay.common.util.XML;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.common.util.sign.encrypt.MD5;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayNotify;
import org.xxpay.pay.channel.shengfutong.SftpayConfig;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

@Service
public class NpsPayNotifyService extends BasePayNotify {

    private final static String logPrefix = "【NPS】";

    @Override
    public String getChannelName() {
        return NpsConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject doNotify(Object notifyData) {
        JSONObject bizContext = getRequestParameters(notifyData);
        _log.info("{}回调解析json数据：{}", logPrefix, bizContext.toString());
        JSONObject retObj = buildFailRetObj();
        try {
            if (!verifyPayParams(bizContext)) {
                retObj.put(PayConstant.RESPONSE_RESULT, SftpayConfig.RESPONSE_RESULT_FAIL);
                return retObj;
            }
            PayOrder payOrder = (PayOrder) bizContext.get("payOrder");
            byte payStatus = payOrder.getStatus(); // 0：订单生成，1：支付中，-1：支付失败，2：支付成功，3：业务处理完成，-2：订单过期
            if (payStatus != PayConstant.PAY_STATUS_SUCCESS && payStatus != PayConstant.PAY_STATUS_COMPLETE) {
                int updatePayOrderRows = rpcCommonService.rpcPayOrderService.updateStatus4Success(payOrder.getPayOrderId());
                if (updatePayOrderRows != 1) {
                    _log.error("{}更新支付状态失败,将payOrderId={},更新payStatus={}失败", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
                    retObj.put(PayConstant.RESPONSE_RESULT, "处理订单失败");
                    return retObj;
                }
                _log.error("{}更新支付状态成功,将payOrderId={},更新payStatus={}成功", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
                payOrder.setStatus(PayConstant.PAY_STATUS_SUCCESS);
            }
            // 业务系统后端通知
            baseNotify4MchPay.doNotify(payOrder, true);
            _log.info("====== 完成处理vippay支付回调通知 ======");
            retObj.put(PayConstant.RESPONSE_RESULT, "success");
        } catch (Exception e) {
            _log.error(e, logPrefix + "处理异常");
        }
        return retObj;
    }
    public boolean verifyPayParams(JSONObject payContext) {
        // 查询payOrder记录
        String payOrderId = payContext.getString("ORDER_ID");
        PayOrder payOrder = rpcCommonService.rpcPayOrderService.findByPayOrderId(payOrderId);
        if (payOrder == null) {
            _log.error("Can't found payOrder form db. payOrderId={}, ", payOrderId);
            payContext.put("retMsg", "Can't found payOrder");
            return false;
        }
        if(!payContext.getString("RESP_CODE").equals("0000")){
            _log.error("订单{}交易失败，回调内容", payOrderId,payContext.toJSONString());
            payContext.put("retMsg", "订单{}交易失败");
            return false;
        }
        NpsConfig npsConfig = new NpsConfig(getPayParam(payOrder));
        String signStr= payContext.getString("ORDER_ID")
                +payContext.getString("ORDER_AMT")
                +payContext.getString("ORDER_TIME")
                +payContext.getString("USER_ID")
                +payContext.getString("BUS_CODE")
                +payContext.getString("RESP_CODE")
                +payContext.getString("RESP_DESC")
                ;
        _log.info("{}回调待签名字符串：{}", logPrefix, signStr);
        String MD5_STR = DigestUtils.md5DigestAsHex(signStr.getBytes()).toUpperCase();
        _log.info("{}回调预签名结果:{}", logPrefix, MD5_STR);
        String sign = SignUtils.MD5.createSign(MD5_STR ,npsConfig.getPrivateKey(), SignUtils.CHARSET_UTF8).toUpperCase().substring(8, 24);
        _log.info("{}回调签名结果:{}", logPrefix, sign);
        if(!payContext.getString("SIGN").equals(sign)) {
            _log.error("验证签名失败. payOrderId={}, ", payOrderId +"验证签名失败" + "systemSign = " +sign  + "上游签名”" + payContext.getString("sign"));
            payContext.put("retMsg", "验证签名失败");
            return false;
        }

        // 核对金额
        long outPayAmt = Util.conversionCentAmount(payContext.getBigDecimal("ORDER_AMT"));
        long dbPayAmt = payOrder.getAmount().longValue();
        if (dbPayAmt != outPayAmt) {
            _log.error("金额不一致. outPayAmt={},transOrderId={}", outPayAmt, payOrderId);
            payContext.put("retMsg", "金额不一致");
            return false;
        }
        payContext.put("payOrder", payOrder);
        return true;
    }
}
